Private Predictions with Syft Keras

Step 1: Public Training

Welcome to this tutorial! In the following notebooks you will learn how to provide private predictions. By private predictions, we mean that the data is constantly encrypted throughout the entire process. At no point is the user sharing raw data, only encrypted (that is, secret shared) data. In order to provide these private predictions, Syft Keras uses a library called TF Encrypted under the hood. TF Encrypted combines cutting-edge cryptographic and machine learning techniques, but you don't have to worry about this and can focus on your machine learning application.

You can start serving private predictions with only three steps:

  • Step 1: train your model with normal Keras.
  • Step 2: secure and serve your machine learning model (server).
  • Step 3: query the secured model to receive private predictions (client).

Alright, let's go through these three steps so you can deploy impactful machine learning services without sacrificing user privacy or model security.

Authors:

On behalf of:

Train your model with Keras

To use privacy-preserving machine learning techniques for your projects you should not have to learn a new machine learning framework. If you have basic Keras knowledge, you can start using these techniques with Syft Keras. If you have never used Keras before, you can learn a bit more about it through the Keras documentation.

Before serving private predictions, the first step is to train your model with normal Keras. As an example, we will train a model to classify handwritten digits. To train this model we will use the canonical MNIST dataset.

We borrow this example from the reference Keras repository. To train your classification model, you just run the cell below.

Import libs


In [ ]:
from __future__ import print_function
import tensorflow.keras as keras
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.layers import Conv2D, AveragePooling2D
from tensorflow.keras.layers import Activation

Set variables


In [ ]:
batch_size = 128
num_classes = 10
epochs = 2

Input image dimensions


In [ ]:
img_rows, img_cols = 28, 28

Load data and split between train and test sets


In [ ]:
(x_train, y_train), (x_test, y_test) = mnist.load_data()

In [ ]:
x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255

print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

Convert class vectors to binary class matrices


In [ ]:
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()

model.add(Conv2D(10, (3, 3), input_shape=input_shape))
model.add(AveragePooling2D((2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(AveragePooling2D((2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(AveragePooling2D((2, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adam(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)

print('Test loss:', score[0])
print('Test accuracy:', score[1])

In [ ]:

Save your model's weights for future private prediction

Great! Your model is trained. Let's save the model weights with model.save(). In the next notebook, we will load these weights in Syft Keras to start serving private predictions.


In [ ]:
model.save('short-conv-mnist.h5')

In [ ]:


In [ ]: